import { Promise } from 'es6-promise';
import * as utils from "../core/utils";
import { BaseModel } from "../core/base.model";
import { Collection , ObjectID } from "mongodb";
import {
    UpdateParam,
    InsertParam,
    FindOneParam,
} from "../core/params";

export interface Banner {
    mid?: string;
    image: string;
    link?: string;
}

export interface Floor {
    title: string;
    link?: string;
    items?: Object[];
    describe?: string;
}

export interface HomeInfo {
    banners: Banner,
    floors: Floor,
    time?: Date,
}

export interface HomeData {
    _id?: ObjectID,
    draft?: HomeInfo,
    online?: HomeInfo,
    offline?: Array<HomeInfo>,
}

export default class HomeModel extends BaseModel {
    constructor( coll : Collection ) {
        super( coll );
        this.setup();
    }

    name() { return 'HomeModel'; }

    setup() {
        let items = {
            draft: {banners: [], floors: [], time: new Date()},
            online: {banners: [], floors: [], time: new Date()},
            offlines: []
        };

        return this.findOne(new FindOneParam({})).then((res) => {
            if(utils.isNotEmpty(res)){
                return;
            }
            return this.insertOne(new InsertParam(items));
        });
    }

    getDraft(): Promise<any> {
        return this.findOne(new FindOneParam({}, {draft: 1, _id: 0}));
    }

    setDraft(draft: Object): Promise<any> {
        draft['time'] = draft['time'] || new Date();
        return this.updateOne(new UpdateParam({}, {$set: {draft: draft}}));
    }

    getBanners(): Promise<any> {
        return this.findOne(new FindOneParam({}, {banner: 'draft.banners', _id: 0}));
    }

    setBanners(banners: Banner[]): Promise<any> {
        let update = {'draft.banners': banners, time: new Date()};
        return this.updateOne(new UpdateParam({}, {$set: update}));
    }

    getFloors(): Promise<any> {
        return this.findOne(new FindOneParam({}, {floors: 'draft.floors', _id: 0}));
    }

    setFloors(floors: Floor[]): Promise<any> {
        let update = {'draft.floors': floors, time: new Date()};
        return this.updateOne(new UpdateParam({}, {$set: update}));
    }

    getPublished(): Promise<any> {
        return this.findOne(new FindOneParam({}, {online: 1, _id: 0}))
    }

    setPublished(time: Date = new Date()): Promise<any> {
        return this.findOne(new FindOneParam({}, {draft: 1, online: 1})).then((result) => {
            let {draft, online} = result;
            draft.time = time;
            online.time = time;
            let update = {$set: {online: draft}, $push:{offlines: online}};
            return this.updateOne(new UpdateParam({}, update)).then( ()=>{
                return {draft, online};
            });
        })
    }
}
